<template>
  <div class="modalbgc">
    <div class="modalbox">
      <div class="top">
        <div class="content">
          <img
            src="@/assets/images/close.png"
            class="close"
            alt=""
            @click="closeFn"
          />
          <ul class="nav">
            <li
              :class="isModal === 'phone' ? 'active' : ''"
              @click="showPhoneModalFn"
            >
              手机号码登录
            </li>
            <li :class="isModal === 'code' ? 'active' : ''" @click="showQrFn">
              微信扫码登录
            </li>
          </ul>
          <!-- 手机号码登录 -->
          <div class="phonemodal" v-show="isModal === 'phone'">
            <!-- 手机号 -->
            <div class="row">
              <input
                type="text"
                placeholder="请输入手机号码"
                v-model="phonenum"
                ref="phoneInput"
              />
            </div>
            <!-- 滑块验证码 -->
            <slide-verify
              :l="42"
              :r="20"
              :w="360"
              :h="140"
              @success="onSuccess"
              @fail="onFail"
              @refresh="onRefresh"
              :slider-text="msg"
              :accuracy="accuracy"
              :imgs="imgArr"
              class="slide-box"
            ></slide-verify>

            <!-- 短信验证码 -->
            <div class="row">
              <input
                type="text"
                placeholder="请输入短信验证码"
                class="captcha"
                v-model="phonecode"
              />
              <span
                :class="{ btn: true }"
                @click="getcode"
                v-show="!isShowCount"
                >获取验证码</span
              >
              <span
                :class="{ btn: true, prohibit: isShowCount }"
                v-show="isShowCount"
                >{{ count }}</span
              >
            </div>
            <button class="loginbtn" @click="submitFn">登录</button>
          </div>

          <!-- 微信扫码登录 -->
          <div class="code" v-show="isModal === 'code'" id="weixin">二维码</div>
        </div>
      </div>
      <div class="bottom"></div>
    </div>
  </div>
</template>

<script>
import {
  SendSMSAPI,
  PhoneReginAPI,
  WechatUsersBindingAPI,
  UserInfoAPI,
} from "@/request/api.js";
import { validateTelephoneNumber } from "@/utils";
import { mapMutations, mapActions, mapState } from "vuex";

export default {
  data() {
    return {
      // isModal: "phone", //显示什么模式登录
      msg: "向右滑动", // 滑块验证码
      // 精确度小，可允许的误差范围小；为1时，则表示滑块要与凹槽完全重叠，才能验证成功。默认值为5
      accuracy: 1,
      // 使用自定义验证码图片
      imgArr: [
        require("@/assets/images/integral-01.9386d4bf.png"),
        require("@/assets/images/integral-02.150d92a1.png"),
        require("@/assets/images/integral-03.9870f3f1.png"),
        require("@/assets/images/integral-04.afadcbdf.png"),
      ],

      phonenum: "", //手机号码
      phonecode: "", //手机短信验证码
      count: 6, //计数值
      isShowCount: false, //是否显示倒计时
    };
  },
  updated() {
    //在登录模态框中,如果刷新页面时,isModal值发生变化,则触发updated
    //如果是isModal是code,此时需要调用该方法才能显示二维码
    if (this.isModal == "code") {
      this.showQrFn();
    }
  },
  computed: {
    ...mapState({
      isModal: (state) => state.showModal.loginByModal,
    }),
  },
  methods: {
    ...mapMutations({
      updateShowModal: "showModal/updateShowModal",
      chanIsLogined: "loginStatus/chanIsLogined",
    }),
    ...mapActions({
      asyncChangeToast: "showToast/asyncChangeToast",
      asyncChangeUserInfo: "userInfo/asyncChangeUserInfo",
    }),
    //显示手机模态框
    showPhoneModalFn() {
      this.updateShowModal({
        loginByModal: "phone",
      });
    },
    // 封装手机和滑块的验证
    toVerify() {
      //1.判断手机号 如果验证不通过 需要提示 需要return
      if (!validateTelephoneNumber(this.phonenum)) {
        // 提示框
        //显示提示框
        this.asyncChangeToast({
          isShowToast: true,
          toastType: "warning",
          toastMsg: "请输入正确的手机号!",
        });
        this.$refs.phoneInput.focus();
        return;
      }
      //2.判读滑块拼图 如果验证不通过，需要提示 需要return
      if (this.msg === "向右滑动" || this.msg === "再来一次") {
        this.asyncChangeToast({
          isShowToast: true,
          toastType: "warning",
          toastMsg: "请滑动滑块验证码!",
        });
        return;
      }
      return true;
    },
    // 关闭模态框
    closeFn() {
      this.updateShowModal({
        isShowModal: false, //是否显示登录模态框
      });
    },
    // 滑块验证码
    // 拼图成功
    onSuccess(times) {
      this.msg = `login success, 耗时${(times / 1000).toFixed(1)}s`;
    },
    // 拼图失败
    onFail() {
      //重新刷新拼图
      this.onRefresh();
    },
    // 刷新
    onRefresh() {
      this.msg = "再来一次";
    },
    //获取验证码
    async getcode() {
      //1.判断手机号 如果验证不通过 需要提示 需要return
      //2.判读滑块拼图 如果验证不通过，需要提示 需要return
      if (!this.toVerify()) {
        return;
      }

      //3.获取验证码(发送请求给后台),页面需要倒计时效果
      // 发送手机验证码请求
      let res = await SendSMSAPI({ phone: this.phonenum.trim() });
      //如果有异常则终止
      if (!res) return;

      //请求成功
      if (res.code == 0) {
        // 验证码倒计时
        this.isShowCount = true;
        let time = this.count;
        let timer = setInterval(() => {
          this.count--;
          if (this.count == 0) {
            //停止定时器，还原count值
            clearInterval(timer);
            this.isShowCount = false;
            this.count = time;
          }
        }, 1000);
      }
    },
    // 校验并登录
    async submitFn() {
      //1.判断手机号 如果验证不通过 需要提示 需要return
      //2.判读滑块拼图 如果验证不通过，需要提示 需要return
      if (!this.toVerify()) return;
      //3.验证手机短信验证码，只能验证是否为空，因为后端没有返回给我们值进行校验
      if (!this.phonecode.trim()) {
        // 显示提示框
        this.asyncChangeToast({
          isShowToast: true,
          toastType: "warning",
          toastMsg: "请输入验证码再进行登录!",
        });
        return;
      }
      // 发送登录请求
      let res = null;
      let uuid = localStorage.getItem("uuid");
      if (uuid) {
        res = await WechatUsersBindingAPI({
          verifyCode: this.phonecode,
          phone: this.phonenum,
          uuid,
        });
      } else {
        res = await PhoneReginAPI({
          verifyCode: this.phonecode,
          phone: this.phonenum,
        });
      }

      if (!res) return;

      if (res.code == 0) {
        //1.提示登录成功
        //显示提示框
        this.asyncChangeToast({
          isShowToast: true,
          toastType: "success",
          toastMsg: "登录成功!",
        });
        //2.存储到本地存储
        localStorage.setItem("x-auth-token", res["x-auth-token"]);
        //3.隐藏登录模态框
        this.updateShowModal({
          isShowModal: false,
        });
        //4.变为登录状态
        this.chanIsLogined(true);
        //5.删除本地的uuid,不然每次我是一个普通的登录,也会是一个关联请求
        // if(uuid){
        //   localStorage.removeItem("uuid");
        // }
        //写法2：短路的写法
        uuid && localStorage.removeItem("uuid");

        //问题：在手机号登录和微信扫码登录和在个人中心也要获取用户信息呢?
        //解决：在vuex中获取数据且把数据共享在vuex中,然后再获取的地方调用该函数即可。
        this.asyncChangeUserInfo();
      }
    },
    //weixin登录
    showQrFn() {
      //显示二维码
      this.updateShowModal({
        loginByModal: "code",
      });
      // this.isModal = "code";
      //获取二维码 并展示
      // 申请微信登录二维码
      let _this = this;
      new WxLogin({
        id: "weixin",
        appid: "wx67cfaf9e3ad31a0d", // 这个appid要填死
        scope: "snsapi_login",
        // 扫码成功后重定向的接口
        redirect_uri: "https://sc.wolfcode.cn/cms/wechatUsers/shop/PC",
        // state填写编码后的url
        state: encodeURIComponent(
          window.btoa("http://127.0.0.1:8080" + _this.$route.path)
        ),
        // 调用样式文件
        href: "data:text/css;base64,LmltcG93ZXJCb3ggLnRpdGxlLC5pbXBvd2VyQm94IC5pbmZvew0KICAgIGRpc3BsYXk6IG5vbmU7DQp9ICAgIA0KLmltcG93ZXJCb3ggcXJjb2Rlew0KICAgIG1hcmdpbi10b3A6IDIwcHg7DQp9",
      });
    },
  },
};
</script>

<style lang="less" scoped>
.modalbgc {
  background: rgba(0, 0, 0, 0.5);
  width: 100%;
  height: 100%;
  position: fixed;
  left: 0;
  top: 0;

  .modalbox {
    width: 555px;
    height: 423px;
    position: absolute;
    left: 50%;
    top: 50%;
    margin-left: -277px;
    margin-top: -211px;

    .top {
      width: 475px;
      height: 403px;
      background-color: #fff;
      margin: 0 auto;
      border-radius: 20px 20px 0 0;
      padding-top: 50px;
      box-sizing: border-box;
      position: relative;

      .close {
        position: absolute;
        right: 20px;
        top: 20px;
        cursor: pointer;
      }

      .content {
        width: 380px;
        height: 306px;
        margin: 0 auto;

        .nav {
          width: 264px;
          height: 30px;
          line-height: 30px;
          display: flex;
          justify-content: space-between;
          margin: 0 auto 20px;

          li {
            font-size: 16px;
            line-height: 23px;
            color: #999999;
            position: relative;
            cursor: pointer;

            &.active {
              color: #000;
            }
          }

          li:nth-of-type(1)::after {
            content: "";
            width: 1px;
            height: 25px;
            background-color: #ccc;
            position: absolute;
            right: -32px;
            top: 0;
          }
        }

        .phonemodal {
          width: 360px;
          height: 266px;
          font-size: 14px;

          .row {
            margin-bottom: 15px;
            input {
              width: 100%;
              height: 50px;
              outline-style: none;
              border-radius: 2px;
              border: 1px solid #d2d2d2;
              text-indent: 1em;
              box-sizing: border-box;
              transition: all 0.6s;

              &.captcha {
                width: 264px;
                height: 50px;
              }

              &:focus {
                border-color: rgb(255, 87, 34);
              }
            }
            .btn {
              width: 90px;
              height: 50px;
              line-height: 50px;
              text-align: center;
              background-color: #0a328e;
              color: #ffffff;
              display: inline-block;
              cursor: pointer;
              margin-left: 5px;

              &.prohibit {
                background-color: #666;
                cursor: no-drop;
              }

              &:not(.prohibit):hover {
                background-color: rgb(59, 91, 165);
              }
            }
          }
          .loginbtn {
            width: 360px;
            height: 50px;
            line-height: 50px;
            text-align: center;
            background-color: #ffffff;
            color: #ffffff;
            background-color: #0a328e;
            cursor: pointer;
            border: 0;
            font-size: 18px;
            transition: all 0.5s;

            &:hover {
              background-color: rgb(59, 91, 165);
            }
          }
        }

        .code {
          text-align: center;
        }
      }
    }
    .bottom {
      height: 20px;
      width: 100%;
      background-color: rgb(227, 234, 246);
      border-radius: 0 0 20px 20px;
    }
  }
}

// 滑块验证码样式优化，注意：需要在该样式前加：/deep/
// 因为，style加了scoped只在当前组件有效，所以要想改变别的组件的样式，则需要加上 /deep/
/deep/.slide-box {
  width: 100%;
  position: relative;
  box-sizing: border-box;
  canvas {
    position: absolute;
    left: 0;
    top: -120px;
    display: none;
    width: 100%;
    box-sizing: border-box;
  }
  .slide-verify-slider {
    margin-bottom: 15px;
    box-sizing: border-box;
  }
  .slide-verify-block {
    width: 85px;
    height: 140px;
  }
  .slide-verify-refresh-icon {
    top: -120px;
    display: none;
  }
  &:hover {
    canvas {
      display: block;
    }
    .slide-verify-refresh-icon {
      display: block;
    }
  }
}
</style>